package il.ac.tau.dbcourse.logic;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import il.ac.tau.dbcourse.db.Album;
import il.ac.tau.dbcourse.db.ConnectionFactory;
import il.ac.tau.dbcourse.db.DBException;
import il.ac.tau.dbcourse.db.PersistenceManager;
import il.ac.tau.dbcourse.db.Track;
import il.ac.tau.dbcourse.db.UserTrack;
import il.ac.tau.dbcourse.db.reports.ExistingTrack;
import il.ac.tau.dbcourse.db.reports.IncompleteAlbum;
import il.ac.tau.dbcourse.db.reports.MissingTrack;
import il.ac.tau.dbcourse.db.reports.ExistingTrack.TrackDetails;
import il.ac.tau.dbcourse.db.reports.IncompleteAlbum.AlbumDetails;

public class MixAndMatch {

	/**
	 * Search for a track the related freedb entry. Should be performed while scanning the HD.
	 * 
	 * @param userTrack
	 * @param conn
	 * @throws DBException
	 */
	public static boolean matchTrack(UserTrack userTrack, Connection conn)
			throws DBException {
		String trackTitle = userTrack.getTitle();
		String albumTitle = userTrack.getAlbumName();
		String artistName = userTrack.getArtistName();
		if (trackTitle != null && trackTitle.compareTo("") != 0) {
			// Try to get by title, album and artist name
			Long[] results = Track.getByTitleAlbumArtist(conn, trackTitle,
					albumTitle, artistName);

			// If no match, try by title and artist name
			if (results.length == 0)
				results = Track.getByTitleArtist(conn, trackTitle, artistName);

			// If no match, try by title and album name
			if (results.length == 0)
				results = Track.getByTitleAlbum(conn, trackTitle, albumTitle);

			// If no match, try by title only
			if (results.length == 0)
				results = Track.getByTitle(conn, trackTitle);

			// not found. keep null.
			if (results.length == 0)
				return false;

			// Update the "luckiest" track as the matched track
			userTrack.setTrack(conn, results[0]);
			PersistenceManager.save(conn, userTrack);
			return true;
		}
		return false;
	}
	private Connection conn;
	public MixAndMatch()throws DBException{
		conn=ConnectionFactory.getConnection();
	}
	public void mix() throws DBException {
		try {
			IncompleteAlbum incompleteAlbum = new IncompleteAlbum(conn);
			MissingTrack missingTrack = new MissingTrack(conn);
			incompleteAlbum.truncate();
			missingTrack.truncate();
			List<UserTrack> tracks = UserTrack.getAllMatched(conn);
			for (UserTrack userTrack : tracks) {
				Track track = userTrack.getTrack();
				Album album = track.getAlbum();
				List<Track> albumTracks = album.getAllTracks(conn);
				for (Track albumTrack : albumTracks) {
					if (!albumTrack.isMatched(conn)) {
						// After the first time the alubm_id is inserted, the rest is just ignored.
						incompleteAlbum.insertId(album.getId());
						missingTrack.insertId(albumTrack.getId());
					}
				}
			}
			incompleteAlbum.close();
			missingTrack.close();
		} catch (SQLException e) {
			throw new DBException("Can't perform mix -" + e.getMessage());
		} 

	}
	public List<Track> getMissingTracks(Album album) throws DBException {
		return MissingTrack.getTracks(conn,album);
	}

	public List<AlbumDetails> getIncompleteAlbums() throws DBException {
		return IncompleteAlbum.getAlbums(conn);
	}
	
	public void close(){
		if (conn!=null)
			try {
				conn.close();
			} catch (SQLException e) {
			}
	}
	
	public List<TrackDetails> getExistingTracks() throws DBException {
		return ExistingTrack.getExistingTracks(conn);
	}
	
	public List<TrackDetails> getExistingTracks(Album album) throws DBException {
		return ExistingTrack.getExistingTracks(conn,album);
	}

	public static void main(String[] args) throws Exception {
		MixAndMatch mixAndMatch = new MixAndMatch();
		
		mixAndMatch.mix();
		List<AlbumDetails> albums=mixAndMatch.getIncompleteAlbums();
		for (AlbumDetails detail:albums){
			System.out.println("Incomplete album - "+detail.getAlbum().getTitle());
			System.out.println("Total songs missing - "+detail.getMissingCount()+" out of "+detail.getSongCount());
			System.out.println("Songs:");
			List<Track> tracks=mixAndMatch.getMissingTracks(detail.getAlbum());
			for (Track track:tracks){
				System.out.println("   "+track.getTitle());
			}
			
			System.out.println();
		}
		
		System.out.println("Existing tracks:");
		List<TrackDetails> tracks=mixAndMatch.getExistingTracks();
		for (TrackDetails detail:tracks){
			System.out.print("    Track name - "+detail.getTrack().getTitle()+"\t\t");
			System.out.println("Path - "+detail.getFilePath());
		}
		mixAndMatch.close();
	}
}
